package org.platform.processor.diagnose.tree.impl;

import com.mc.mic.core.tool.helper.SpringContextHelper;
import org.platform.constant.DiagnoseConst;
import org.platform.core.JobManager;
import org.platform.mo.db.FdDiagnoseTaskTreeNode;
import org.platform.processor.diagnose.job.PromoteTreeDiagnoseDetailJob;
import org.platform.processor.diagnose.tree.IFaultTreeNodeDiagnose;
import org.platform.tool.helper.LogHelper;
import org.platform.tool.util.ComUtils;
import org.quartz.JobKey;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.JobDetailImpl;

import java.util.List;


/**
 * 故障树节点诊断抽象类
 * 只需要子类重写 doExecute()方法即可
 * <p>
 * <注意>
 * 如果当诊断结果为超时的状态,需要手动设置状态或结果为超时
 *
 * @author FengJie
 * @date 2018/8/1
 */
public abstract class AbstractFaultTreeNodeDiagnose implements IFaultTreeNodeDiagnose {


    /**
     * 具体的执行的抽闲方法,有执行类去完成
     *
     * @param treeNode 节点信息
     * @return
     */
    public abstract boolean doExecute(FdDiagnoseTaskTreeNode treeNode);

    @Override
    public boolean doDiagnose(FdDiagnoseTaskTreeNode thisNode, List<FdDiagnoseTaskTreeNode> diagnoseList) {
        //初始化并且推送
        start(thisNode);
        promoteTreeDiagnoseDetail(diagnoseList);

        boolean result = doExecute(thisNode);

        //保存日志并且推动
        end(result, thisNode);


        System.out.println("当前:" + thisNode.getName() + "   " + getStatus(thisNode.getStatus()));
        System.out.println();
        diagnoseList.forEach(list -> {
            System.out.println(list.getName() + "   " + getStatus(list.getStatus()));
        });


        promoteTreeDiagnoseDetail(diagnoseList);
        return result;
    }

    String getStatus(Integer i) {
        switch (i) {
            case 0:
                return "等待";
            case 1:
                return "执行";
            case 2:
                return "成功";
            default:
                return "失败";
        }
    }

    /**
     * 诊断开始初始化
     *
     * @param treeNode 节点信息
     */
    private void start(FdDiagnoseTaskTreeNode treeNode) {
        treeNode.setStatus(DiagnoseConst.DIAGNOSE_STATUS_EXECUTE);
        treeNode.setStarttime(System.currentTimeMillis());
        treeNode.setEndtime(System.currentTimeMillis());
    }

    /**
     * 诊断结束初始化
     *
     * @param diagnoseStatus 诊断状态
     * @param treeNode       节点信息
     */
    private void end(boolean diagnoseStatus, FdDiagnoseTaskTreeNode treeNode) {
        // 注意     如果判断为超时,需要底层手动设置其中一个状态
        if (treeNode.getStatus() == DiagnoseConst.DIAGNOSE_STATUS_ABORT
                || treeNode.getResult() == DiagnoseConst.DIAGNOSE_RESULT_ABORT) {
            treeNode.setResult(DiagnoseConst.DIAGNOSE_RESULT_ABORT);
            treeNode.setStatus(DiagnoseConst.DIAGNOSE_STATUS_ABORT);
        } else {
            if (diagnoseStatus) {
                treeNode.setResult(DiagnoseConst.DIAGNOSE_RESULT_SUCCESS);
                treeNode.setStatus(DiagnoseConst.DIAGNOSE_STATUS_SUCCESS);
            } else {
                treeNode.setResult(DiagnoseConst.DIAGNOSE_RESULT_FAILURE);
                treeNode.setStatus(DiagnoseConst.DIAGNOSE_STATUS_FAILURE);
            }
        }
        treeNode.setEndtime(System.currentTimeMillis());
        saveDiagnoseLog(diagnoseStatus, treeNode);
    }

    /**
     * 保存诊断日志
     */
    private void saveDiagnoseLog(boolean diagnoseStatus, FdDiagnoseTaskTreeNode treeNode) {
        LogHelper logHelper = SpringContextHelper.getBean(LogHelper.class);
        String status;
        //保存每次的诊断日志
        if (diagnoseStatus) {
            treeNode.setResult(DiagnoseConst.DIAGNOSE_RESULT_SUCCESS);
            status = "【正常】";
        } else {
            treeNode.setResult(DiagnoseConst.DIAGNOSE_RESULT_FAILURE);
            status = "【异常】";
        }
        String content = "故障树节点:" + treeNode.getName() + "的最终诊断状态" + status;
        logHelper.normal(content, treeNode.getDiagnoseid(), treeNode.getDeviceid());
    }

    /**
     * 推送故障树节点诊断详情
     */
    private void promoteTreeDiagnoseDetail(List<FdDiagnoseTaskTreeNode> diagnoseList) {
        JobManager jobManager = SpringContextHelper.getBean(JobManager.class);
        JobDetailImpl jd = new JobDetailImpl();
        jd.setJobClass(PromoteTreeDiagnoseDetailJob.class);
        jd.setKey(JobKey.jobKey(ComUtils.getUUID()));
        jd.getJobDataMap().put(PromoteTreeDiagnoseDetailJob.DATA_KEY, diagnoseList);

        SimpleTrigger trigger = TriggerBuilder.newTrigger()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule())
                .startNow()
                .build();

        jobManager.register(jd, trigger);
    }

}
